home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
ada
/
gwuada_9.zip
/
RECOVER.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-27
|
18KB
|
756 lines
/*
* Copyright (C) 1985-1992 New York University
*
* This file is part of the Ada/Ed-C system. See the Ada/Ed README file for
* warranty (none) and distribution info and also the GNU General Public
* License for more details.
*/
#include "hdr.h"
#include "ada.h"
#include "miscp.h"
#include "prsutilp.h"
#include "followp.h"
#include "actionp.h"
#include "lookupp.h"
#include "pspansp.h"
#include "adalexp.h"
#include "errsp.h"
#include "recoverp.h"
/* Variables needed for scope and secondary recoveries */
extern int *open_seq;
/* struct two_pool *closer_toksyms;
struct two_pool *closer_bottom; */
extern int n_open_seq;
extern int n_closer_toksyms;
extern int nps;
extern struct two_pool *closer_toksyms;
extern char *CLOSER_MESSAGE_SYMS();
extern char closer_candidates[13][3][5];
#define EQ(s, t) (strcmp(s, t) == 0)
char *err_message(int k, struct prsstack *curtok) /*;err_message*/
{
/* Form error message for secondary recovery
* The parameter 'k' indicates the point in the parse and state stacks
* at which the recovery is being made
*/
char *e_m_s,
*err_mess;
/* k is index into state stack (not parse stack because it is off by 1) */
int pp = stack_size(sta_stack) - k;
struct prsstack *prs_stack_k = prs_stack;
if (k == 1)
/* this is case where there is 1 element on the state stack and
* the parse stack is empty (i.e. all input is rejected)
*/
return ("Unexpected input");
while (--pp >= 0)
prs_stack_k = prs_stack_k-> prev;
if (EQ((err_mess = err_msg_syms(prs_stack_k->symbol)) , "")) {
int act;
struct two_pool *sta_stack_k = sta_stack;
int kk = stack_size(sta_stack) - k;
while (--kk >= 0)
sta_stack_k = sta_stack_k -> link;
act = action((int)(sta_stack_k->val.state), curtok->symbol);
if (act > NUM_STATES) {
e_m_s = err_msg_syms(lhs[act - NUM_STATES - 1]);
return(EQ(e_m_s , "") ? "Unexpected input" : e_m_s);
}
else
return ("Unexpected input");
}
else
return (err_mess);
}
int prs_block(struct two_pool *states, struct two_pool *toks) /*;prs_block*/
{
/* This parse checker returns true if the parse blocks and false if
* it does not or if it cannot be determined that it will block.
* The sequence of states need not be complete, so it is possible
* for a reduction to use up all the states. This makes the goto
* undetermined. In such a case the FOLLOW set for the left hand
* side is used. If the next token is not in the follow set, then
* surely the parse must block eventually, but if it is not, we have
* to conclude that not blocking is possible. The value returned is
* the predicate 'the parse must block if the state stack contains
* states as a suffix and the token sequence contains toks as a pre-
* fix'.
*/
int act, red, nolh, n;
int ts;
struct two_pool *top_tp;
struct two_pool *tmp_tp;
int cs;
short n_states = 1;
ts = toks->val.state; /* ts frome toks */
toks = toks->link;
cs = states->val.state; /* cs = top(states) */
while(1) { /* while true */
act = action(cs, ts);
if (act == 0)
return 1; /* parse error */
else if (act < NUM_STATES) { /* shift action */
if (toks == (struct two_pool *)0)
return 0;
/* tmp_tp = toks; destroys prs_toks!! */ /* for re-use */
ts = toks->val.state; /* next token */
toks = toks->link;
tmp_tp = TALLOC();
tmp_tp->link = states;
tmp_tp->val.state = (cs = act); /* update stateseq */
states = tmp_tp;
n_states ++;
}
else if ((red = (act - NUM_STATES )) == 0) /* accept action */
return 0;
else { /* reduce action */
int nn;
red --; /* Adjust for 0 offset arrays */
nolh = lhs[red];
n = n_states - rhslen[red] + 1;
nn = rhslen[red];
if (n <= 1)
return (is_terminal(ts) && !in_FOLLOW(nolh, ts) );
/* replace rhs states with lhs
* states[n] = (cs = action(states(n - 1), nolh));
*/
if (nn == 0) {
tmp_tp = TALLOC();
tmp_tp->link = states;
states = tmp_tp;
}
else if (nn > 1 ) {
top_tp = states;
while (--nn > 1)
states = states->link;
tmp_tp = states;
states = states->link;
TFREE(top_tp, tmp_tp);
}
states->val.state =
(cs = action((int)(states->link->val.state), nolh));
/* n_states -= nn; */
n_states -= rhslen[red] - 1;
}
}
}
int prs_check(struct two_pool *stateseq, int *tokseq, int n_tokseq)
/*;prs_check*/
{
int ts;
int cs;
struct two_pool *top_tp;
struct two_pool *tmp_tp;
struct two_pool *temp_stateseq;
int n_temp_stateseq;
int nsh;
int red, act;
/* This is just a parser that operates from the token sequence, tokseq.
* It returns when an error occurrs, an accept occurs, or the sequence
* of tokens is exhausted.
*/
/* n_tokseq is actually the size of tokseq - 1. It is used as an offset
* into tokseq (which starts at zero). However, when the size of tokseq
* is desired, we use (n_tokseq + 1)
*/
copystack(stateseq, &temp_stateseq, &n_temp_stateseq);
nsh = 0; /* Number of tokens shifted */
ts = tokseq[n_tokseq]; /* Top of tokseq */
cs = temp_stateseq->val.state; /* Top of stateseq */
while(1) /* while true */
{
act = action(cs, ts);
if (act == 0)
return nsh; /* parse error */
else if (act < NUM_STATES) /* Shift action */
{
if ( (++nsh ) >= (n_tokseq + 1)) /* up shift count */
return nsh; /* gone far enough */
ts = tokseq[n_tokseq - nsh]; /* next token */
tmp_tp = TALLOC(); /* Update stateseq */
tmp_tp->val.state = ( cs = act);
tmp_tp->link = temp_stateseq;
temp_stateseq = tmp_tp;
}
else if ((red = (act - NUM_STATES )) == 0 ) /* accept action */
return ((ts == EOFT_SYM) ? (n_tokseq + 1) : nsh);
else { /* reduce action */
int nn;
red --; /* adjust for 0 offset arrays */
nn = rhslen[red];
/* replace rhs states with lhs
*
* stateseq(nn..) := [cs := ACTION(stateseq(nn-1), nolh)];
*
* Since the top element will be replaced, we strip off nn - 1
* elements and then replace the top one.
* There are 3 cases :
* nn == 0 : allocate a new top element
* for the state stack
* nn == 1 : Leave the top element for
* replacement
* nn > 1 : Strip nn - 1 off the stack.
* leaving the top element for
* replacement
*/
if ( nn == 0 ) {
tmp_tp = TALLOC();
tmp_tp->link = temp_stateseq;
temp_stateseq = tmp_tp;
}
else if (nn > 1) {
top_tp = temp_stateseq;
while (--nn > 1)
temp_stateseq = temp_stateseq->link;
tmp_tp = temp_stateseq;
temp_stateseq = temp_stateseq->link;
TFREE(top_tp, tmp_tp);
}
/* Replace the top element with the GOTO */
temp_stateseq->val.state =
(cs = action((int)(temp_stateseq->link->val.state), lhs[red]));
}
}
}
int scope_recovery(int k, int index, int *open_seq) /*;scope_recovery*/
{
int exists = 0;
int open_loc;
struct prsstack *prstmp;
int opener;
struct two_pool *tmp_tp, *saved_tail, *closer_head, *closer_tail;
struct two_pool *STA_STACK;
int closer;
int i, closer_index;
int kk = k;
int ind;
int *tmp_toksyms;
int n_tmp_toksyms;
int prs_distance;
int check_dist;
int n_closer;
/* The parameter 'k' indicates the portion of the state stack with
* which the parse check is to be performed. The parameter
* 'index' indicates the portion of the parse stack to be used when
* looking for the next opener to be closed.
*/
/*
* if not exists ind in [index .. n_open_seq]
* | k >= open_seq(ind) then
* return false;
* end if;
*
* Assume that no such ind exists. Loop through, looking for
* one.
*/
#ifdef EDEBUG
if (trcopt)
fprintf(errfile, "AT PROC: scope_recovery(%d, %d, %d)\n", k, index,
*open_seq);
#endif
for ( ind = index; ind < n_open_seq; ind++ )
if ( k - 1 >= open_seq[ind]) {
/* adjust to k-1 because in C version (only), size of
* parse stack is 1 less than size of state stack
*/
exists = 1;
break;
}
if (!exists)
return 0;
open_loc = nps - open_seq[ind];
for (prstmp = prs_stack; open_loc--; prstmp = prstmp->prev);
opener = prstmp->symbol;
/* Keep